<?php

namespace App\Services;

/**
 * 此类被所有验证规则类继承
 *
 * Class Validate
 * @package App\Services
 */
abstract class ProjectValidate {

    // 是否使用true基础的验证规则
    protected $useBaseRules = true;
    // 基础的验证规则
    protected $baseRule = [
        'id'            => 'int|min:0',
        'pid'           => 'int|min:0',
        'parent_id'     => 'int|min:0',
        'level'         => 'int|min:0|max:100',
        'status'        => 'int',
        'order'         => 'int',
        'page'          => 'int|min:1',
        'listRows'      => 'int|min:0|max:100',
        'list_rows'     => 'int|min:0|max:100',
        'phone'         => 'regex:/^1\d{10}/|size:11',
        'sex'           => 'in:gent,lady,no',
        'token'         => 'alpha_num|size:32',
        'app_key'       => 'alpha_num|size:32',
        'app_id'        => 'int|min:1',
    ];
    // 基础的验证提示消息
    protected $baseMessage = [
        'id'            => 'ID必须是大于等于0的整数',
        'pid'           => '父ID必须是大于等于0的整数',
        'parent_id'     => '父ID必须是大于等于0的整数',
        'level.integer' => '层级必须是整数',
        'level.between' => '层级必须是0-100的整数',
        'status.integer'=> 'status状态必须是整数',
        'order.integer' => 'order排序必须是整数',
    ];
    // 基础的验证字段
    protected $baseField = [];

    # 当前验证规则
    public $rules = [];
    # 当前验证错误信息
    public $messages = [];
    # 当前验证字段名
    public $attributes = [];


    public function __construct()
    {
        // 如果使用基础验证规则
        if ($this->useBaseRules) {
            $this->rules    = array_merge($this->baseRule, $this->rules);
            $this->messages = array_merge($this->baseMessage, $this->messages);
            $this->attributes   = array_merge($this->baseField, $this->attributes);
        }
    }

    /**
     * 自定义子类初始化
     * @param array $initData
     * @return mixed
     */
    abstract public function initValidate($initData = []);

    /**
     * 验证方法
     *
     * @param $data     验证数据
     * @param array $keysMap            验证数据的key值映射
     * @param bool $throwException      是否抛出异常
     * @param array $initValidateData   实例化验证类参数
     * @param null $errorCallback       错误时的回调
     * @return mixed
     * @throws \App\Exceptions\RequestFailException
     */
    public static function checkValidate($data, array $keysMap = [], $throwException = true, $initValidateData = [], $errorCallback = null)
    {
        # 实例化对象
        $curValidate = app()->make(static::class);
        $curValidate->initValidate($initValidateData);

        #
        $rules  = pick_array($curValidate->rules, $keysMap);
        $messages = $curValidate->messages;
        $attributes = pick_array($curValidate->attributes, array_values($keysMap));

//        # 查看验证
//        dd($curValidate, $data, $rules, $messages, $attributes);

        return check_validate($data, $rules, $messages, $attributes, $throwException, $errorCallback);
    }
}